//
//  Copyright (C) 2015 Sereina Riniker
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#include <GraphMol/RDKitBase.h>
#include <Geometry/Utils.h>
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <GraphMol/Substruct/SubstructMatch.h>
#include <RDGeneral/utils.h>
#include <RDGeneral/RDLog.h>
#include <RDGeneral/Exceptions.h>
#include <boost/dynamic_bitset.hpp>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <RDGeneral/StreamOps.h>

#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
#include <boost/flyweight.hpp>
#include <boost/flyweight/key_value.hpp>
#include <boost/flyweight/no_tracking.hpp>

namespace ForceFields {
namespace CrystalFF {
using namespace RDKit;

/* SMARTS patterns for experimental torsion angle preferences
 * taken from J. Med. Chem. 56, 1026-2028 (2013)
 *
 * torsion-angle potential form:
 * V = V1*(1 + s1*cos(1x)) + V2*(1 + s2*cos(2x)) + V3*(1 + s3*cos(1x))
 *     + V4*(1 + s4*cos(1x)) + V5*(1 + s5*cos(1x)) + V6*(1 + s6*cos(1x))
 *
 * format: [SMARTS, s1, V1, s2, V2, s3, V3, s4, V4, s5, V5, s6, V6]
 */
const std::string torsionPreferences =
    "[O:1]=[C:2]!@;-[O:3]~[CH0:4] -1 78.2 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]!@;-[O:3]~[CH0:4] -1 78.2 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]([N])!@;-[O:3]~[C:4] -1 79.1 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]!@;-[O:3]~[C:4] -1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]!@;-[O:3]~[!#1:4] -1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][O:2]!@;-[c:3]~[*:4] 1 0.0 1 0.8 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][O:2]!@;-[CX3:3]~[*:4] 1 0.0 1 0.0 1 0.0 -1 1.0 1 0.0 1 0.0\n"
    "O=[C:1][O:2]!@;-[CH1:3][H:4] -1 20.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][O:2]!@;-[CH2:3]~[C:4] 1 0.0 1 0.0 1 2.5 1 0.0 1 0.0 1 0.0\n"
    "[H:1][CX4H1:2]!@;-[O:3][CX4:4] -1 20.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[C:1][CH2:2]!@;-[O:3][CX4:4] 1 0.0 1 0.0 1 2.5 1 0.0 1 0.0 1 0.0\n"
    "[*:1][CX4:2]!@;-[O:3][CX3:4](=[!O]) 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1][CX4:2]!@;-[O:3][CX4:4] 1 0.0 1 0.0 1 8.8 1 0.0 1 0.0 1 0.0\n"
    "[*:1][CX4:2]!@;-[O:3][CX4:4] 1 0.0 1 0.0 1 2.5 1 0.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[O:3][S:4] 1 0.0 1 3.2 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([cH0])!@;-[O:3][S:4] 1 0.0 1 8.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[O:3][S:4] 1 0.0 1 11.5 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[O:3][c:4] 1 0.0 1 0.0 1 0.0 -1 0.5 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([cH0])!@;-[O:3][c:4] 1 0.0 1 0.0 -1 3.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[O:3][c:4] 1 0.0 1 2.7 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[O:3][!C;!H:4] 1 0.0 -1 5.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]([cH1])!@;-[O:3][!C;!H:4] 1 0.0 -1 5.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[O:3][!C;!H:4] 1 0.0 1 0.0 1 0.0 -1 2.0 1 0.0 1 "
    "0.0\n"
    "[cH:1][c:2]([cH])!@;-[O:3][C:4](F)(F)[F] 1 0.0 1 30.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    //"[cH0:1][c:2]([cH0])!@;-[O:3][CX4:4]([!#1])([!#1])([!#1])\n"
    "[a:1][c:2]([a])!@;-[O:3][CX4H0:4] 1 0.0 1 0.0 1 0.0 -1 2.0 1 0.0 1 0.0\n"
    "[cH1,n:1][c:2]!@;-[O:3][CRH1:4] 1 0.0 -1 5.4 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH1,n:1][c:2]!@;-[O:3][CH1:4] 1 0.0 -1 7.2 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][c:2]([cH0])!@;-[O:3][CX4H0:4] -1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    //"[cH0:1][c:2]([cH0])!@;-[O:3][CX4H0:4]\n"
    "[cH0:1][c:2]([nX2])!@;-[O:3][C:4] 1 110.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[nX2:1][c:2]([nX2])!@;-[O:3][C:4] 1 0.0 -1 44.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[nX2:1][c:2]([nX3])!@;-[O:3][C:4] -1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([nX3])!@;-[O:3][C:4] -1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([nX2])!@;-[O:3][C:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1]([CX3])[c:2]([cH1])!@;-[O:3][C:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "[cH1:1][c:2](cO)!@;-[O:3][C:4] -1 61.9 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O[c:1][c:2](cO)!@;-[O:3][C:4] 1 0.0 1 3.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[O:3][C:4] 1 0.0 1 6.6 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH1])!@;-[O:3][C:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[O:3][C:4] 1 0.0 -1 19.5 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[O:3][CX3H0:4] 1 0.0 1 1.9 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[O:3][!#1:4] 1 0.0 1 6.6 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[aH0:1][c:2]!@;-[OX2:3][!#1:4] 1 0.8 1 0.7 -1 -0.3 -1 2.5 -1 -0.1 1 -0.8\n"
    //"[cH1,nX3H1:1][c:2]([cH0])!@;-[O:3][CX4H0:4]\n"
    "[!#1:1][CX4H0:2]!@;-[OX2:3][!#1:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[H:1][CX4H1:2]!@;-[OX2:3][!#1:4] -1 5.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[C:1][CX4H2:2]!@;-[OX2:3][c:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][CX4H2:2]!@;-[OX2:3][C:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[C:1][CX4H2:2]!@;-[OX2:3][C:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][CX4H2:2]!@;-[OX2:3][c:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4H2:2]!@;-[OX2:3][c:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4H2:2]!@;-[OX2:3][C:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][CX4H2:2]!@;-[OX2:3][!#1:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[C:1][CX4H2:2]!@;-[OX2:3][!#1:4] -1 -3.5 1 2.5 -1 -2.3 1 0.6 -1 -0.4 -1 "
    "0.4\n"
    "[!#1:1][CX4H2:2]!@;-[OX2:3][!#1:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[OX2:3][!#1:4] -1 -3.5 1 2.5 -1 -2.3 1 0.6 -1 -0.4 -1 "
    "0.4\n"
    "O=[CX3:1][NX3H0:2](C)!@;-[CX4H2:3][C:4] 1 0.0 1 8.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[CX3:1][NX3H1:2]!@;-[CX4H2:3][C:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "O=[S:1](=O)[NX3H0:2]!@;-[CX4H2:3][!#1:4] 1 0.0 1 1.9 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[S:1](=O)[NX3H1:2]!@;-[CX4H2:3][!#1:4] 1 17.9 -1 -13.3 1 9.2 1 4.7 -1 "
    "-2.3 -1 -0.9\n"
    "O=[S:1](=O)[NX3H0:2]!@;-[CX4H1:3][H:4] 1 0.0 -1 15.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[S:1](=O)[NX3H1:2]!@;-[CX4H1:3][H:4] -1 20.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[S:1](=O)[NH1:2]!@;-[c:3][nX2:4] 1 0.0 -1 15.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[S:1](=O)[NH0:2]!@;-[c:3]([cH1])[cH1:4] 1 0.0 1 13.3 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "O=[S:1](=O)[NH1:2]!@;-[c:3]([cH1])[cH1:4] 1 0.0 1 0.0 1 0.0 1 0.9 1 0.0 1 "
    "0.0\n"
    "O=[S:1](=O)[NH0:2]!@;-[c:3]([cH1])[cH0:4] 1 0.0 1 50.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "O=[S:1](=O)[NH1:2]!@;-[c:3]([cH1])[cH0:4] 1 1.9 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[S:1](=O)[NH0:2]!@;-[c:3]([cH0])[cH0:4] 1 0.0 1 17.8 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "O=[S:1](=O)[NH1:2]!@;-[c:3]([cH0])[cH0:4] 1 0.0 1 10.6 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "O=[S:1](=O)[N:2]!@;-[c:3][a:4] 1 0.0 1 0.0 1 0.0 -1 2.0 1 0.0 1 0.0\n"
    "[O-:1][N+:2](=O)!@;-[c:3]([cH,nX2H0])[cH,nX2H0:4] 1 0.0 -1 5.0 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[O-:1][N+:2](=O)!@;-[c:3]([cH0])[cH,nX2H0:4] -1 -0.2 1 -5.7 1 -0.2 -1 "
    "-3.2 1 0.1 1 -1.3\n"
    "[O-:1][N+:2](=O)!@;-[c:3]([cH0])[cH0:4] -1 -0.4 1 0.3 1 -0.1 -1 0.6 1 "
    "-0.1 -1 0.2\n"
    "[O-:1][N+:2](=O)!@;-[c:3][a:4] 1 0.0 -1 11.8 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[NX3H1:3][C,c:4] 1 0.0 1 0.0 1 0.0 -1 0.8 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]([cH1])!@;-[NX3H1:3][C,c:4] 1 15.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]([nX2H0])!@;-[NX3H1:3][C,c:4] 1 40.0 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "[cH0:1][c:2]([nX3H1])!@;-[NX3H1:3][C,c:4] 1 50.0 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[NX3H1:3][C,c:4] 1 0.0 -1 1.4 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH1:1][c:2]([nX3H1])!@;-[NX3H1:3][C,c:4] 1 0.0 -1 100.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[nX2H0:1][c:2]([nX2H0])!@;-[NX3H1:3][C,c:4] 1 0.0 -1 15.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[nX2H0:1][c:2]([nX3H1])!@;-[NX3H1:3][C,c:4] 1 0.0 -1 27.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[a:1][a:2]!@;-[NH1:3][C,c:4] 1 0.0 -1 6.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[C:1][NH:2]!@;-[C:3](=[NH2:4])[NH2] 1 0.0 -1 100.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[NH2][C:1](=[NH2])[NH:2]!@;-[CH2:3][C:4] 1 0.0 1 0.0 1 2.5 1 0.0 1 0.0 1 "
    "0.0\n"
    "[a:1][c:2]!@;-[NX2:3]=[C:4]([NX3])n -1 -0.1 1 1.9 -1 -0.1 -1 -1.9 -1 0.1 "
    "1 0.0\n"
    "[nX2:1][c:2]!@;-[NX2:3]=[C:4]([NX3])N 1 0.0 -1 6.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]!@;-[NX2:3]=[C:4]([NX3])N -1 -0.1 1 1.9 -1 -0.1 -1 -1.9 -1 "
    "0.1 1 0.0\n"
    "[cH1:1][c:2]!@;-[NX2:3]=[C:4]([NX3])N 1 -0.4 -1 -0.9 1 -0.4 1 1.1 1 -0.2 "
    "1 -0.1\n"
    "[O:1]=[C:2]([NH1])!@;-[NX3H1:3](C=O)[H:4] -1 144.7 1 0.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[O:1]=[C:2]!@;-[NX3H1:3](C=O)[H:4] 1 0.0 -1 10.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]!@;-[NX3:3](C=O)[*:4] 1 0.0 -1 10.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX3:3]=[NX2:4] 1 63.8 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H0:2]!@;-[CX3:3]=[*H0:4] 1 0.0 -1 8.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H0:2]!@;-[CX3:3]=[*H1:4] 1 0.0 1 0.0 1 2.5 1 0.0 1 0.0 1 0.0\n"
    //"O=[C:1][NX3H0:2]!@;-[CX3:3]=[*H2:4] \n"
    "O=[C:1][NX3H1:2]!@;-[CX3:3]=[*H2:4] 1 0.0 -1 68.5 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX3:3]=[*H1:4] 1 0.0 1 0.0 -1 2.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX3:3]=[*H0:4] 1 0.0 -1 39.4 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H0:2]!@;-[CX3H1:3]=[*:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX3H1:3]=[*:4] 1 84.1 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX3:3]=[*:4] 1 0.0 -1 33.2 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H0:2]!@;-[CX4H2:3][c:4]([cH,nX2H0])[cH,nX2H0] 1 0.0 1 3.0 1 "
    "0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX4H2:3][c:4]([cH,nX2H0])[cH,nX2H0] -1 -1.3 1 1.6 -1 "
    "-0.6 -1 0.6 1 -0.1 -1 0.3\n"
    "O=[C:1][NX3H0:2]!@;-[CX4H2:3][!#1:4] 1 0.0 1 15.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX4H2:3][!#1:4] 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H0:2]!@;-[CX4H1:3][H:4] 1 0.0 -1 8.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX4H1:3][H:4] -1 5.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H0:2]!@;-[CX4H0:3][C:4] 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[CX4H0:3][C:4] 1 0.0 1 0.0 1 2.5 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3:2]!@;-[!#1:3][!#1:4] 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 0.7\n"
    "O=[C:1][NX3H0:2]!@;-[c:3]([s,o])[n:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H1:2]!@;-[c:3]([s,o])[n:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3:2]!@;-[a:3]([s,o])[a:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H1:2]!@;-[c:3]([cH,nX2H0])[cH,nX2H0:4] 1 0.0 -1 2.8 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    //"O=[C:1][NX3:2]!@;-[a:3]([nX2H0])[cH0:4]\n"
    "O=[C:1][NX3H1:2]!@;-[a:3]([nX2H0])[cH1:4] -1 22.9 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "O=[C:1][NX3:2]!@;-[a:3]([nX2H0])[cH1:4] -1 21.4 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3:2]!@;-[a:3][nH:4] -1 53.3 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[c:3]([cH0]Cl)[cH:4] -1 20.0 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[c:3]([cH0]F)[cH:4] -1 11.4 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3:2]!@;-[a:3]([cH1])[aH0:4]!@;-O 1 38.2 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "O=[C:1][NX3:2]!@;-[a:3][aH0:4] 1 0.0 1 0.0 1 0.0 -1 0.7 1 0.0 1 0.0\n"
    "O=[C:1][NX3H1:2]!@;-[c:3]([cH1])[cH1:4] 1 0.0 -1 2.1 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H0:2]!@;-[c:3]([cH1])[cH1:4] 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 "
    "0.8\n"
    "O=[C:1][NX3H0:2]!@;-[c:3]([cH0])[cH:4] 1 0.0 1 2.4 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H1:2]!@;-[c:3]([cH0])[cH:4] -1 9.7 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H0:2]!@;-[c:3]([cH0])[cH0:4] 1 0.0 1 2.9 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H1:2]!@;-[c:3]([cH0])[cH0:4] 1 0.0 1 2.9 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "O=[C:1][NX3H0:2]!@;-[a:3][a:4] 1 0.0 1 0.7 1 0.0 1 0.0 1 0.0 -1 0.3\n"
    "O=[C:1][NX3H1:2]!@;-[a:3][a:4] 1 0.0 -1 3.1 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[CX3:2]([NX3H1]C)!@;-[NX3H1:3][!#1:4] -1 51.7 1 0.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[O:1]=[C:2]([!NH1])!@;-[NX3H1:3]([H:4])(c([nX2H0])([nX2H0])) 1 100.0 1 "
    "0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]([NH1])!@;-[NX3H1:3]([H:4])(c([nX2H0])([nX2H0])) -1 100.0 1 "
    "0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]!@;-[NX3H1:3]([H:4])(c([nX2H0])([nX2H0])) 1 0.0 -1 100.0 1 0.0 "
    "1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]!@;-[NX3H1:3]([H:4])(cn) 1 0.0 -1 50.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[O:1]=[C:2]!@;-[NX3H0:3]([a:4])[A] 1 0.0 -1 4.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[CX3:2](a)!@;-[NX3H0:3][!#1:4] 1 0.0 -1 13.9 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[O:1]=[CX3:2]!@;-[NX3H0:3][!#1:4] 1 0.0 -1 8.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[CX3:2]!@;-[NX3H1:3][!#1:4] -1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[CH0:1][NX3:2]([CH0])!@;-[c:3][a:4] 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[CH0:1][NX3:2]([CH1])!@;-[c:3][a:4] 1 0.0 1 0.0 1 0.0 -1 0.7 1 0.0 1 0.0\n"
    "[cH1,nX2H0:1][c:2]([cH1,nX2H0])!@;-[NX3&r:3][*:4] 1 0.0 -1 0.9 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[cH1,nX2H0:1][c:2]([cH1,nX2H0])!@;-[NX3&r:3][CX4&r:4] 1 0.0 -1 3.7 1 0.0 "
    "1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[NX3H1:3][CX4&r:4]([C&r])([C&r]) 1 0.0 -1 6.8 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[NX3:3][CX4:4] 1 0.0 1 -0.7 1 0.0 1 -0.5 1 0.0 1 "
    "-0.6\n"
    "[cH0:1][c:2]([cH,nX2H0])!@;-[NX3H1:3][CX4:4] 1 73.1 1 0.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[cH0:1][c:2]([cH,nX2H0])!@;-[NX3H0:3][CX4:4] 1 0.0 1 0.0 1 0.8 1 0.0 1 "
    "0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[NX3:3][CX4:4] 1 0.0 1 0.0 1 0.0 -1 2.0 1 0.0 1 "
    "0.0\n"
    "[c:1][c:2](c)!@;-[NX3:3][CX4:4] 1 0.0 -1 0.5 1 0.0 -1 0.8 1 0.0 1 -0.6\n"
    "[cH1:1][c:2]([cH1])!@;-[NX3:3][a:4] 1 0.0 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([cH0])!@;-[NX3:3][a:4] 1 0.0 1 0.0 -1 3.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[NX3:3][a:4] 1 0.0 1 1.3 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][a:2]!@;-[NX3H0:3][CX3:4]=O 1 0.0 1 2.3 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][a:2]!@;-[NX3H1:3][CX3:4]=O -1 -1.6 -1 -0.6 1 0.6 -1 0.0 -1 0.1 1 "
    "-0.5\n"
    //"[nX2H0:1][a:2]([nX2H0])!@;-[NX3H0:3][CX3:4]=O\n"
    "[nX2H0:1][a:2]([!nX2H0])!@;-[NX3H1:3][CX3:4](A)=O 1 72.8 1 0.0 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][a:2]([!nX2H0])!@;-[NX3H1:3][CX3:4](a)=O 1 72.8 1 0.0 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][a:2]([!nX2H0])!@;-[NX3H1:3][CX3:4](C)=O 1 72.8 1 0.0 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][a:2]([!nX2H0])!@;-[NX3H1:3][CX3:4]([NX3H1])=O 1 72.8 1 0.0 1 "
    "0.0 1 0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][a:2]([!nX2H0])!@;-[NX3H1:3][CX3:4]([OX2])=O 1 72.8 1 0.0 1 0.0 "
    "1 0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][a:2]([!nX2H0])!@;-[NX3H1:3][CX3:4]=O 1 72.8 1 0.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[nX2H0:1][a:2]!@;-[NX3H1:3][CX3:4]=O 1 0.0 -1 34.4 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[a:1][a:2]!@;-[NX3H0:3][CX3:4]=O 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 0.6\n"
    "[a:1][a:2]!@;-[NX3H1:3][CX3:4]=O 1 0.0 -1 3.1 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][a:2]!@;-[NX3:3][CX4H0:4] 1 0.0 1 0.0 1 0.0 -1 4.0 1 0.0 1 0.0\n"
    "[a:1][a:2]!@;-[NX3:3][!#1:4] 1 0.0 1 -0.7 1 0.0 1 -0.5 1 0.0 1 -0.6\n"
    "[O:1]=[CX3:2]!@;-[nX3:3]([aH0:4])([aH0]) 1 0.0 -1 8.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[O:1]=[CX3:2]!@;-[nX3:3][aH1:4] 1 0.0 -1 18.7 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[CX3:2]!@;-[nX3:3][aH0:4] 1 0.0 -1 6.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][CX3:2](=S)!@;-[NX3:3][a:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX3:2](=S)!@;-[NX3H0:3][!#1:4] 1 0.0 -1 22.5 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[!#1:1][CX3:2](=S)!@;-[NX3H1:3][!#1:4] 1 0.0 -1 20.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[!#1:1][CH2:2]!@;-[n:3][cH0:4] 1 0.0 1 6.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CH2:2]!@;-[n:3][a:4] 1 0.0 1 8.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[CX4:1][CX4H2:2]!@;-[NX3;N^3:3][CX4:4] 1 4.0 1 3.1 1 3.9 -1 -0.8 1 0.0 1 "
    "0.7\n"
    "[CX4:1][CX4H2:2]!@;-[NX3:3][CX4:4] 1 4.0 1 3.1 1 3.9 -1 -0.8 1 0.0 1 0.7\n"
    "[C:1][CX4H2:2]!@;-[NX3;N^3:3][C:4] 1 4.0 1 3.1 1 3.9 -1 -0.8 1 0.0 1 0.7\n"
    "[C:1][CX4H2:2]!@;-[NX3:3][C:4] 1 4.0 1 3.1 1 3.9 -1 -0.8 1 0.0 1 0.7\n"
    "[C:1][CX4:2]!@;-[NX3;N^3:3][C:4] 1 1.9 1 1.6 1 2.3 -1 -0.5 1 -0.1 1 0.2\n"
    "[C:1][CX4:2]!@;-[NX3:3][C:4] 1 0.0 1 0.0 1 1.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4H2:2]!@;-[NX3H1;N^3:3][!#1:4] -1 -3.1 1 1.5 -1 -1.6 1 0.2 -1 "
    "-0.2 1 -0.2\n"
    "[!#1:1][CX4H2:2]!@;-[NX3H1:3][!#1:4] 1 0.0 1 0.0 1 1.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4H2:2]!@;-[NX3;N^3:3][!#1:4] 1 0.0 1 0.0 1 1.7 1 0.0 1 0.0 1 "
    "0.0\n"
    "[!#1:1][CX4H2:2]!@;-[NX3:3][!#1:4] 1 0.0 1 0.0 1 1.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[NX3;N^3:3][!#1:4] 1 0.0 1 0.0 1 1.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[NX3:3][!#1:4] 1 0.0 1 0.0 1 1.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][S:2](=O)(=O)!@;-[nX3:3]([aH1])[aH1:4] 1 0.0 1 20.5 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[!#1:1][S:2](=O)(=O)!@;-[nX3:3][aH0:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[!#1:1][S:2](=O)(=O)!@;-[nX3:3][a:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[c:1][S:2](=O)(=O)!@;-[NX2H0:3]-[*:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[*:1][S:2](=O)(=O)!@;-[NX3H0&r:3][*:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[C:1][S:2](=O)(=O)!@;-[NX3H1:3][c:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[C:1][S:2](=O)(=O)!@;-[NX3H0:3][c:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[c:1][S:2](=O)(=O)!@;-[NX3H1:3][C:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[c:1][S:2](=O)(=O)!@;-[NX3H0:3][C:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[c:1][S:2](=O)(=O)!@;-[NX3H1:3][c:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[c:1][S:2](=O)(=O)!@;-[NX3H0:3][c:4] 1 0.0 1 4.1 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[C:1][S:2](=O)(=O)!@;-[NX3H1:3][C:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[C:1][S:2](=O)(=O)!@;-[NX3H0:3][C:4] 1 0.0 1 16.0 1 5.0 1 7.0 1 0.0 1 "
    "0.0\n"
    "[*:1][S:2](=O)(=O)!@;-[NX3H1:3][*:4] 1 0.0 1 1.2 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[*:1][S:2](=O)(=O)!@;-[NX3H0:3][*:4] 1 0.0 1 3.7 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX3:2]!@;-[SX2:3][!#1:4] 1 0.0 -1 2.5 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[SX2:3][!#1:4] -1 -0.8 -1 -0.8 -1 -1.5 -1 0.4 1 -0.1 -1 "
    "0.3\n"
    "[!#1:1][CX3:2]!@;-[SX3:3][!#1:4] -1 5.5 1 8.7 -1 3.1 1 5.0 1 -1.7 1 1.0\n"
    "[!#1:1][CX4:2]!@;-[SX3:3][!#1:4] 1 0.0 1 0.0 1 10.4 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX3:2]!@;-[SX4:3][!#1:4] 1 0.0 1 3.8 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[H:1][CX4H1:2]!@;-[SX4:3][!#1:4] 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[SX4:3][!#1:4] 1 0.0 1 0.0 1 5.0 1 0.0 1 0.0 1 0.0\n"
    "[aH1:1][c:2]([aH1])!@;-[SX2:3][!#1:4] 1 0.0 1 0.0 1 0.0 -1 0.9 1 0.0 1 "
    "0.0\n"
    "[aH1:1][c:2]([aH0])!@;-[SX2:3][!#1:4] 1 0.0 1 0.0 1 0.0 -1 0.9 1 0.0 1 "
    "0.0\n"
    "[aH0:1][c:2]([aH0])!@;-[SX2:3][!#1:4] 1 -0.2 1 0.4 -1 -0.0 -1 1.9 -1 -0.0 "
    "1 -1.1\n"
    "[!#1:1][c:2]!@;-[SX2:3][!#1:4] 1 0.0 1 0.0 1 0.0 -1 4.4 1 0.0 1 0.0\n"
    "[!#1:1][c:2]!@;-[SX3:3][!#1:4] 1 0.0 1 1.3 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[aH1:1][c:2]([aH1])!@;-[SX4:3][!#1:4] 1 0.0 1 1.5 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[aH0:1][c:2]([aH1])!@;-[SX4:3][!#1:4] 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[aH0:1][c:2]([aH0])!@;-[SX4:3][!#1:4] 1 0.0 1 3.3 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[!#1:1][c:2]!@;-[SX4:3][!#1:4] 1 0.0 1 1.5 1 0.0 1 0.0 1 0.0 1 0.0\n"
    //"[O:1]=[CX3:2]([NH1])!@;-[CH2:3][CX3:4]=O\n"
    "[O:1]=[CX3:2]([NH1])!@;-[CH2:3][C:4] -1 8.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[C]\\[CX3:1]([H])=[CX3:2]([C])!@;-\\[CH2:3][C:4] 1 0.0 1 0.0 -1 5.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[C]\\[CX3:1]([H])=[CX3:2]([H])!@;-\\[CH1:3](C)[C:4] 1 0.0 1 0.0 -1 5.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[C]\\[CX3:1]([H])=[CX3:2]([H])!@;-\\[CH2:3][C:4] 1 0.0 1 0.0 -1 5.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[C]\\[CX3:1]([H])=[CX3:2]([H])!@;-/[CH2:3][C:4] 1 0.0 1 0.0 -1 5.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[N:1][C:2](=O)!@;-[CX4H2:3][CX4H2:4] 1 4.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "N[C:2](=[O:1])!@;-[CH2:3][N:4] 1 0.0 -1 10.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]([O-])!@;-[CX4H1:3][H:4] 1 0.0 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0\n"
    "[CX3H2:1]=[CX3:2]!@;-[CX3:3]=[C:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[CX3:1]=[CX3:2]!@;-[CH2:3][OX2:4] 1 0.0 1 0.0 -1 20.0 1 0.0 1 0.0 1 0.0\n"
    "[CX3:1]=[CX3:2]!@;-[CH1:3](C)[C:4] 1 0.0 1 0.0 -1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[CX3:1]=[CX3:2]!@;-[CH2:3][C:4] 1 0.0 1 0.0 -1 1.5 1 0.0 1 0.0 1 0.0\n"
    "[CX3:1]=[CX3:2]!@;-[CH2:3][c:4] 1 0.0 1 0.0 -1 1.5 1 0.0 1 0.0 1 0.0\n"
    "[CX3:1]=[CX3:2]!@;-[CH2:3][!#1:4] 1 0.0 1 0.0 -1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[CX3:2]!@;-[CX3:3]=[O:4] 1 20.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[CX3:1]=[CX3:2]!@;-[CX3:3]=[CX3:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[*^2:1]~[C^2:2]([!H])!@;-[C^2:3]~[*^2:4] 1 0.0 -1 15.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "[*^2:1]~[C^2:2]!@;-[C^2:3]~[*^2:4] 1 0.0 -1 30.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[CX3:2]!@;-[CX4&r3:3]!@[!#1:4] -1 -0.7 -1 0.5 1 -0.3 -1 0.3 -1 -0.2 "
    "-1 0.2\n"
    "[O:1]=[CX3:2]!@;-[CX4H1&r3:3][H:4] 1 0.0 -1 3.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[OX2:1][CX4H2:2]!@;-[CX4H2:3][N&r:4] 1 0.0 1 0.0 1 5.0 1 0.0 1 0.0 1 0.0\n"
    "[OX2:1][CX4H2:2]!@;-[CX4H2:3][N:4] 1 0.0 1 0.0 1 10.0 1 0.0 1 0.0 1 0.0\n"
    "[OX2:1][CX4:2]!@;-[CX4:3][N:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[OX2:1][CX4H2:2]!@;-[CX4H2:3][OX2:4] 1 0.0 1 0.0 1 10.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[OX2:1][CX4:2]!@;-[CX4:3][OX2:4] 1 0.0 1 0.0 1 3.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4&r:2]!@;-[CX4&r:3][!#1:4] 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4H2:2]!@;-[CX4H2:3][!#1:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[CX4:3][!#1:4] 1 0.0 1 0.0 1 7.0 1 0.0 1 0.0 1 0.0\n"
    "[OH1:1][CX4:2]!@;-[CX3:3]=[O:4] 1 0.0 -1 2.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[NH1:1][CX4:2]!@;-[CX3:3]=[O:4] 1 0.0 -1 2.1 -1 -0.1 -1 -1.0 1 -0.4 1 "
    "-0.1\n"
    "[O:1][CX4:2]!@;-[CX3:3]=[O:4] 1 0.0 -1 3.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[N:1][CX4:2]!@;-[CX3:3]=[O:4] 1 0.0 -1 1.4 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[C:1][CX4H2:2]!@;-[CX3:3]=[O:4] 1 -1.0 1 -0.5 1 -0.2 1 -0.3 -1 0.0 1 "
    "-0.3\n"
    "[c:1][CX4H2:2]!@;-[CX3:3]=[O:4] -1 0.9 1 -0.3 1 -0.2 1 -0.5 -1 0.1 1 0.2\n"
    "[!#1:1][CX4H2:2]!@;-[CX3:3]=[O:4] 1 0.0 1 -0.7 1 0.0 1 -0.5 1 0.0 1 -0.6\n"
    "[c:1][CX4:2]!@;-[CX3:3]=[O:4] 1 0.0 1 0.0 -1 1.0 1 0.0 1 0.0 1 0.0\n"
    //"[C:1][CX4:2]!@;-[CX3:3]=[O:4]\n"
    //"[!#1:1][CX4:2]!@;-[CX3:3]=[O:4]\n"
    "[c:1][CX4:2]!@;-[CX3:3][C:4] 1 0.0 1 0.0 1 1.9 1 0.0 1 0.0 1 0.0\n"
    "[C:1][CX4:2]!@;-[CX3:3][c:4] 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][CX4:2]!@;-[CX3:3][c:4] -1 -4.4 1 4.0 -1 -3.9 -1 -1.0 1 0.6 -1 -0.4\n"
    "[C:1][CX4:2]!@;-[CX3:3][C:4] 1 0.0 1 0.0 1 1.5 1 0.0 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[CX3H0:3][!#1:4] 1 0.0 1 0.0 1 0.6 1 0.0 1 0.0 1 0.0\n"
    "[H:1][CX4H1:2]!@;-[CX3:3][!#1:4] -1 0.7 -1 0.5 1 0.3 -1 -0.3 1 0.0 1 "
    "-0.1\n"
    "[!#1:1][CX4H2:2]!@;-[CX3:3][!#1:4] 1 0.0 1 0.0 1 0.0 -1 0.8 1 0.0 1 0.0\n"
    "[!#1:1][CX4:2]!@;-[CX3:3][!#1:4] 1 0.0 1 0.0 1 0.6 1 0.0 1 0.0 1 0.0\n"
    "[c:1][c:2]!@;-[c:3][c:4]!@c 1 0.1 1 0.9 1 0.1 -1 -0.4 1 0.0 -1 0.3\n"
    "[cH0:1][c:2]([cH0])!@;-[c:3]([cH0:4])[cH0] 1 0.0 1 3.6 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[c:3]([cH0:4])[cH1] 1 0.0 1 10.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "[cH0:1][c:2]([cH1])!@;-[c:3]([cH0:4])[cH1] -1 -0.7 1 3.6 -1 -0.8 1 1.7 -1 "
    "-0.1 1 0.2\n"
    "[cH0:1][c:2]([cH0])!@;-[c:3]([cH1:4])[cH1] 1 -0.3 -1 -2.1 -1 -0.1 -1 -0.3 "
    "1 0.0 -1 0.5\n"
    "[cH0:1][c:2]([cH1])!@;-[c:3]([cH1:4])[cH1] 1 0.0 1 0.0 1 0.0 1 0.6 1 0.0 "
    "1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[c:3]([cH1:4])[cH1] -1 -0.7 1 -8.0 1 0.0 1 4.4 1 "
    "0.0 1 -1.5\n"
    "[nX2H0:1][c:2]!@;-[c:3][nX3H1:4] 1 0.0 -1 30.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][c:2]([!nX2H0])!@;-[c:3]([!nX2H0])[nX2H0:4] 1 100.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][c:2](a(a)(a))!@;-[c:3][nX2H0:4] 1 30.0 1 0.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    //"[nX2H0:1][c:2](a([CX3H0]))!@;-[c:3](a([CX3H0]))[nX2H0:4] \n"
    "[nX2H0:1][c:2]!@;-[c:3][nX2H0:4] 1 0.0 -1 50.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][c:2]!@;-[c:3][s,o,nX3H1:4] 1 0.0 -1 4.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[c:3][nX2H0:4] 1 0.0 1 1.7 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]!@;-[c:3]([cH0])[nX2H0:4] -1 0.9 -1 -1.0 1 -0.8 -1 0.2 -1 0.3 "
    "1 -0.2\n"
    "[c:1][c:2]!@;-[c:3]([cH0])[nX2H0:4] 1 0.0 1 0.0 1 0.0 1 1.1 1 0.0 1 0.0\n"
    "[c:1][c:2]([cH0])!@;-[c:3][nX2H0:4] 1 0.0 -1 3.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][c:2]!@;-[c:3][nX2H0:4] 1 0.0 -1 4.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][c&r5:2]!@;-[c&r5:3][c:4] 1 0.0 -1 20.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][c&r6:2]!@;-[c&r5:3][c:4] 1 0.0 -1 5.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][c&r6:2]!@;-[c&r6:3][cH0:4] 1 0.0 1 3.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[c:1][c&r6:2]!@;-[c&r6:3][c:4] 1 0.0 1 0.0 1 0.0 -1 0.5 1 0.0 1 0.0\n"
    "[c:1][c:2]!@;-[c:3][c:4] 1 0.0 1 0.0 1 0.0 -1 0.5 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H0:3][a:4] 1 0.0 1 0.0 1 8.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H0:3][N,O,S:4] 1 0.0 1 0.0 1 8.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H0:3][CX3:4] 1 0.0 1 0.0 1 12.5 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H0:3][CX4:4] 1 0.0 1 0.0 1 8.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H0:3][*:4] 1 0.0 1 0.0 1 3.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H2:3][a:4] -1 -1.3 1 1.6 -1 -0.6 -1 0.6 1 -0.1 -1 "
    "0.3\n"
    "[cH0:1][c:2]!@;-[CX4H2:3][CX3:4] -1 -1.3 1 1.6 -1 -0.6 -1 0.6 1 -0.1 -1 "
    "0.3\n"
    "[cH1:1][c:2]([cH1])!@;-[CX4H2:3][CX4H1:4]C(=O)(O) 1 0.0 1 4.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[CX4H2:3][CX4:4] 1 0.0 1 3.6 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]!@;-[CX4H2:3][CX4:4] -1 -1.3 1 1.6 -1 -0.6 -1 0.6 1 -0.1 -1 "
    "0.3\n"
    "[cH0:1][c:2]!@;-[CX4H2:3][N,O,S:4] 1 0.3 1 1.1 -1 -1.0 1 -0.6 -1 -0.5 1 "
    "0.1\n"
    "[cH0:1][c:2]!@;-[CX4H2:3][!#1:4] -1 -1.3 1 1.6 -1 -0.6 -1 0.6 1 -0.1 -1 "
    "0.3\n"
    "[cH0:1][c:2]!@;-[CX4H1:3][a:4] 1 0.9 1 1.2 1 0.6 1 0.4 1 0.0 1 0.1\n"
    "[cH0:1][c:2]!@;-[CX4H1:3][CX4:4] 1 6.1 1 5.2 1 2.4 -1 -1.4 1 0.3 -1 0.1\n"
    "[cH0:1][c:2]!@;-[CX4H1:3][CX3:4] 1 0.0 1 0.0 1 0.0 1 1.5 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H1:3][N,O,S:4] 1 0.0 1 0.0 1 0.0 1 2.0 1 0.0 1 0.0\n"
    "[cH0:1][c:2]!@;-[CX4H1:3][H:4] 1 0.0 -1 4.3 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H0:3][a:4] 1 0.0 -1 -0.3 -1 -0.1 1 0.1 1 -0.0 -1 0.1\n"
    "[a:1][c:2]!@;-[CX4H0:3][CX3:4] 1 0.0 1 0.0 1 0.0 1 1.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H0:3][CX4:4] 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 3.0\n"
    "[a:1][c:2]!@;-[CX4H0:3][N,O:4] 1 0.0 -1 0.8 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H0:3][*:4] 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 5.0\n"
    "[a:1][c:2]!@;-[CX4H2:3][a:4] 1 0.0 1 1.2 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H2:3][CX3:4] 1 0.0 1 1.2 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H2:3][CX4:4] 1 0.0 1 1.0 1 0.0 -1 1.1 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H2:3][N,O:4] 1 0.0 1 0.0 1 0.0 -1 0.1 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H2:3][!#1:4] 1 0.0 1 3.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H1:3][N,O:4] 1 0.0 1 0.0 1 0.0 1 0.5 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H1:3][a:4] 1 0.0 1 0.6 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[CX4H1:3][H:4] 1 0.0 -1 0.7 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[C:3](=[N:4][CX4H1])(N[CX4H1]) 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0 -1 5.0\n"
    "[a:1][c:2]!@;-[C:3](=[N:4][CX4])(N[CX4]) 1 0.0 -1 0.6 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[a:1][c:2]!@;-[C:3](=[NH0:4][CX4]) 1 0.0 -1 15.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[C:3](=[N:4][!#1])(N[!#1]) 1 0.0 -1 0.6 1 0.0 1 0.3 1 0.0 "
    "-1 -0.1\n"
    "[a:1][c:2]!@;-[C:3](=[N:4][!#1])(N~[!#1]) 1 0.0 1 -0.8 1 0.0 1 0.2 1 0.0 "
    "1 0.0\n"
    "[nX2H0:1][c:2]!@;-[C:3](=[N:4])(-[NH1,NH2]) 1 0.0 -1 26.9 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[nX2H0:1][c:2]!@;-[C:3](=[NH1,NH2:4]) 1 0.0 -1 100.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[C:3](=[N:4]) 1 0.0 -1 30.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]!@;-[C:3](=[N:4]) 1 0.0 -1 10.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][c:2]!@;-[C:3](=[N:4]) 1 0.0 -1 5.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3][a:4]C(=O)(O) 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 "
    "5.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3][a:4][CX3]=O 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 "
    "20.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3][nX3H1:4] 1 0.0 -1 30.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3][nX2H0:4] 1 0.0 -1 30.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3]([cH0])[cH0:4] 1 0.3 -1 -0.6 -1 0.1 -1 0.4 1 "
    "-0.0 -1 0.5\n"
    "[O:1]=[C:2]([O-])!@;-[c:3]([cH1])[cH0:4]([NH1,NH2]) 1 0.0 -1 30.0 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3]([cH1])[cH0:4] 1 0.0 -1 7.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3]([cH1])[cH1:4] 1 0.0 -1 7.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[O:1]=[C:2]([O-])!@;-[c:3][a:4] 1 0.0 -1 25.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1]([OH1])[a:2]!@;-[CX3:3](=[O:4])([NX3H0,CX4H0,c]) -1 14.8 1 0.0 1 0.0 "
    "1 0.0 1 0.0 1 0.0\n"
    "[a:1]([NH1,NH2])[a:2]!@;-[CX3:3](=[O:4])([NX3H0,CX4H0,c]) -1 36.2 1 0.0 1 "
    "0.0 1 0.0 1 0.0 1 0.0\n"
    //"[c:1]([OH1])[c:2]!@;-[CX3:3](=[O:4])([NX3H0])\n"
    //"[c:1]([NH1,NH2])[c:2]!@;-[CX3:3](=[O:4])([NX3H0])\n"
    "[c:1]([OH1])[c:2]!@;-[CX3:3](=[O:4])([O]) 1 0.0 -1 100.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[c:1]([NH1,NH2])[c:2]!@;-[CX3:3](=[O:4])([O]) 1 0.0 -1 20.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[a:1]([OH1])[a:2]!@;-[CX3:3](=[O:4])([O]) 1 0.0 -1 100.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[a:1]([NH1,NH2])[a:2]!@;-[CX3:3](=[O:4])([O]) 1 0.0 -1 100.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[c:1]([OH1])[c:2]!@;-[CX3:3](=[O:4])([!O]) 1 0.0 -1 20.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[c:1]([NH1,NH2])[c:2]!@;-[CX3:3](=[O:4])([!O]) -1 36.5 1 0.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[a:1]([OH1])[a:2]!@;-[CX3:3](=[O:4])([!O]) 1 0.0 -1 100.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[a:1]([NH1,NH2])[a:2]!@;-[CX3:3](=[O:4])([!O]) -1 41.7 1 0.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[cH0:1]([CX3])[c:2]([cH1])!@;-[CX3:3](c)=[O:4] -1 3.1 -1 -3.3 -1 1.9 1 "
    "1.6 1 -0.3 1 0.1\n"
    "[cH0:1][c:2]([cH0])!@;-[CX3:3](c)=[O:4] 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 "
    "5.0\n"
    "[cH0:1]([OH1])[c:2]([cH1])!@;-[CX3:3](c)=[O:4] -1 16.7 1 0.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[cH0:1][c:2]([cH1])!@;-[CX3:3](c)=[O:4] -1 1.0 1 0.0 -1 0.7 1 0.5 -1 -0.0 "
    "1 -0.3\n"
    "[cH1:1][c:2]([cH1])!@;-[CX3:3](c)=[O:4] -1 -0.1 -1 2.4 1 -0.4 -1 -1.0 1 "
    "0.1 -1 -0.5\n"
    "[a:1][a:2]!@;-[CX3:3](a)=[O:4] -1 -0.0 1 -0.9 -1 0.1 1 0.2 -1 0.0 -1 "
    "-0.3\n"
    "[s:1][c:2]!@;-[C:3]([NH1])=[O:4] -1 36.5 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH0:1](Cl)[c:2]([cH1])!@;-[CX3:3]([NX3H1])=[O:4] 1 0.0 1 10.0 1 0.0 1 "
    "0.0 1 0.0 1 0.0\n"
    "[cH0:1](F)[c:2]([cH1])!@;-[CX3:3]([NX3H1])=[O:4] 1 6.2 1 0.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[cH0:1]([OH0])[c:2]([cH1])!@;-[C:3](=O)[NH1:4] -1 60.0 1 0.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    "[cH0:1]([OH1])[c:2]([cH1])!@;-[C:3](=O)[NH1:4] 1 0.0 -1 15.0 1 0.0 1 0.0 "
    "1 0.0 1 0.0\n"
    //"[cH0:1][c:2]([cH1])!@;-[CX3:3]([NX3H1])=[O:4] 1 -0.2 1 -0.9 -1 -0.4 -1 " // 27.6.16 change in functional form
    //"-0.1 1 0.5 1 -0.8\n"
    "[cH0:1][c:2]([cH1])!@;-[CX3:3]([NX3H1])=[O:4] 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.1 1 0.0\n"
    "[cH0:1][c:2]([cH1])!@;-[CX3:3]([NX3H0])=[O:4] 1 0.0 1 5.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[C:3]([NH1,NH2])=[O:4] 1 0.0 -1 0.5 1 0.0 1 0.0 1 " // 27.6. reduced from 1.6
    "0.0 1 0.0\n"
    //"[a:1][c:2]!@;-[C:3]([NH0])=[O:4]\n"
    "[a:1][c:2]!@;-[C:3]([NH1,NH2])=[O:4] 1 0.0 -1 2.4 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1](F)[c:2]([cH1])!@;-[CX3:3]=[O:4] 1 0.0 -1 1.8 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1](Cl)[c:2]([cH1])!@;-[CX3:3]=[O:4] 1 0.0 1 0.0 1 0.0 1 0.0 1 0.0 -1 " // 26.6.16 reduced from 10.0
    "2.0\n"
    "[nX3H1:1][a:2]!@;-[CX3:3]=[O:4] 1 0.0 -1 10.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[nX2H0:1][c:2](c)!@;-[CX3:3]([!O])=[O:4] 1 66.5 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[nX2H0:1][a:2]([nX2H0])!@;-[CX3:3]=[O:4] 1 0.0 -1 36.8 1 0.0 1 0.0 1 0.0 "
    "1 0.0\n"
    "[*^2]!@;-[cH0:1][c:2]([cH1])!@;-[CX3:3]=[O:4] 1 0.0 -1 8.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[cH0:1][c:2]([cH1])!@;-[CX3:3]=[O:4] 1 0.0 -1 2.0 1 0.0 1 0.0 1 0.0 1 " // 25.6.16 reduced from 10.0
    "0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[CX3:3]=[O:4] 1 0.0 1 0.0 1 0.0 -1 3.0 1 0.0 1 "
    "0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[CX3:3]([CX3H0])=[O:4] 1 0.0 -1 5.9 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[CX3:3]=[O:4] 1 0.0 -1 5.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[a:1][a:2]!@;-[CX3:3]=[O:4] 1 0.0 -1 8.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[cH1:1][c:2]([nX2])!@;-[CX3:3]=[NX3:4] 1 0.0 -1 8.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH1:1][c:2]([nX3H1])!@;-[CX3:3]=[NX2:4] 1 97.4 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH1:1][c:2]([nX2])!@;-[CX3:3]=[NX2:4] 1 0.0 -1 8.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH1:1][c:2]([cH0]([OH1]))!@;-[CX3:3]=[NX2:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0 1 0.0\n"
    "[cH1:1][c:2]([cH0])!@;-[CX3:3]=[NX2:4] 1 100.0 1 0.0 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH1:1][c:2]([cH1])!@;-[CX3:3]=[NX2:4] 1 0.0 -1 9.5 1 0.0 1 0.0 1 0.0 1 "
    "0.0\n"
    "[cH0:1][c:2]([cH0])!@;-[CX3:3]=[NX2:4] 1 0.0 1 -0.7 1 0.0 1 -0.5 1 0.0 1 "
    "-0.6\n"
    "[a:1][c:2]!@;-[CX3:3]=[CX3H0:4] 1 0.0 -1 0.7 1 0.0 1 0.6 1 0.0 1 -0.5\n"
    "[a:1][a:2]!@;-[CX3:3]=[CX3H2:4] 1 0.0 -1 1.3 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[a:1][a:2]!@;-[CX3:3]=[CX3H1:4] 1 0.0 -1 5.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[*:1][SX2:2]!@;-[SX2:3][*:4] 1 0.0 1 12.9 1 0.0 1 0.0 1 0.0 1 0.0\n"
    // ------
    //  these patterns were added as part of the ET-DG work
    // non-aromatic double bonds
    //"[*:1][CX3:2]=[CX3:3][*:4] 1 0.0 -1 7.0 1 0.0 1 0.0 1 0.0 1 0.0\n"
    "[*:1][X3,X2:2]=[X3,X2:3][*:4] 1 0.0 -1 100.0 1 0.0 1 0.0 1 0.0 1 0.0\n";

//! A structure used to the experimental torsion patterns
struct ExpTorsionAngle {
  std::string smarts;
  std::vector<double> V;
  std::vector<int> signs;
  boost::shared_ptr<const ROMol> dp_pattern;
  unsigned int idx[4];
};

// class to store the experimental torsion angles
class ExpTorsionAngleCollection {
 public:
  typedef std::vector<ExpTorsionAngle> ParamsVect;
  static const ExpTorsionAngleCollection *getParams(
      const std::string &paramData = "");
  ParamsVect::const_iterator begin() const { return d_params.begin(); };
  ParamsVect::const_iterator end() const { return d_params.end(); };
  ExpTorsionAngleCollection(const std::string &paramData);

 private:
  ParamsVect d_params;  //!< the parameters
};

typedef boost::flyweight<
    boost::flyweights::key_value<std::string, ExpTorsionAngleCollection>,
    boost::flyweights::no_tracking>
    param_flyweight;

const ExpTorsionAngleCollection *ExpTorsionAngleCollection::getParams(
    const std::string &paramData) {
  const ExpTorsionAngleCollection *res = &(param_flyweight(paramData).get());
  return res;
}

ExpTorsionAngleCollection::ExpTorsionAngleCollection(
    const std::string &paramData) {
  boost::char_separator<char> tabSep(" ", "", boost::drop_empty_tokens);
  std::string params;
  if (paramData == "") {
    params = torsionPreferences;
  } else {
    params = paramData;
  }
  std::istringstream inStream(params);

  std::string inLine = RDKit::getLine(inStream);
  while (!inStream.eof()) {
    if (inLine[0] != '#') {
      ExpTorsionAngle angle;
      tokenizer tokens(inLine, tabSep);
      tokenizer::iterator token = tokens.begin();
      angle.smarts = *token;
      ++token;
      for (unsigned int i = 0; i < 12; i += 2) {
        angle.signs.push_back(boost::lexical_cast<int>(*token));
        ++token;
        angle.V.push_back(boost::lexical_cast<double>(*token));
        ++token;
      }
      angle.dp_pattern =
          boost::shared_ptr<const ROMol>(SmartsToMol(angle.smarts));
      // get the atom indices for atom 1, 2, 3, 4 in the pattern
      for (unsigned int i = 0; i < (angle.dp_pattern.get())->getNumAtoms();
           ++i) {
        Atom const *atom = (angle.dp_pattern.get())->getAtomWithIdx(i);
        int num;
        if (atom->getPropIfPresent("molAtomMapNumber", num)) {
          if (num > 0 && num < 5) {
            angle.idx[num - 1] = i;
          }
        }
      }
      d_params.push_back(angle);
    }
    inLine = RDKit::getLine(inStream);
  }  // while loop
  // std::cerr << "Exp. torsion angles = " << d_params.size() << " "
  //    << d_params[d_params.size()-1].smarts << std::endl;
}

void getExperimentalTorsions(
    const RDKit::ROMol &mol, std::vector<std::vector<int> > &expTorsionAtoms,
    std::vector<std::pair<std::vector<int>, std::vector<double> > >
        &expTorsionAngles,
    std::vector<std::vector<int> > &improperAtoms, bool useExpTorsions,
    bool useBasicKnowledge, bool verbose) {
  unsigned int nb = mol.getNumBonds();
  unsigned int na = mol.getNumAtoms();
  if (!na) {
    throw ValueErrorException("molecule has no atoms");
  }

  // check that vectors are empty
  expTorsionAtoms.clear();
  expTorsionAngles.clear();
  improperAtoms.clear();

  unsigned int aid1, aid2, aid3, aid4;
  unsigned int bid2;

  boost::dynamic_bitset<> doneBonds(nb);

  if (useExpTorsions) {
    // we set the torsion angles with experimental data
    const ExpTorsionAngleCollection *params =
        ExpTorsionAngleCollection::getParams();

    // loop over patterns
    for (ExpTorsionAngleCollection::ParamsVect::const_iterator it =
             params->begin();
         it != params->end(); ++it) {
      std::vector<MatchVectType> matches;
      SubstructMatch(mol, *(it->dp_pattern.get()), matches, false, true);

      // loop over matches
      for (std::vector<MatchVectType>::const_iterator matchIt = matches.begin();
           matchIt != matches.end(); ++matchIt) {
        // get bond indices
        aid1 = (*matchIt)[it->idx[0]].second;
        aid2 = (*matchIt)[it->idx[1]].second;
        aid3 = (*matchIt)[it->idx[2]].second;
        aid4 = (*matchIt)[it->idx[3]].second;
        // FIX: check if bond is NULL
        bid2 = mol.getBondBetweenAtoms(aid2, aid3)->getIdx();
        if (!doneBonds[bid2]) {
          doneBonds[bid2] = 1;
          std::vector<int> atoms(4);
          atoms[0] = aid1;
          atoms[1] = aid2;
          atoms[2] = aid3;
          atoms[3] = aid4;
          expTorsionAtoms.push_back(atoms);
          expTorsionAngles.push_back(std::make_pair(it->signs, it->V));
          if (verbose) {
            std::cout << it->smarts << ": " << aid1 << " " << aid2 << " "
                      << aid3 << " " << aid4 << ", (";
            for (unsigned int i = 0; i < it->V.size() - 1; ++i) {
              std::cout << it->V[i] << ", ";
            }
            std::cout << it->V[it->V.size() - 1] << ") " << std::endl;
          }
        }  // if not donePaths
      }    // end loop over matches

    }  // end loop over patterns
  }

  // apply basic knowledge such as flat aromatic rings, other sp2-centers,
  // straight triple bonds, etc.
  if (useBasicKnowledge) {
    boost::dynamic_bitset<> doneAtoms(na);
    ROMol::ADJ_ITER nbrIdx;
    ROMol::ADJ_ITER endNbrs;

    // inversion terms (improper torsions / out-of-plane bends / inversion)
    // loop over atoms
    for (aid2 = 0; aid2 < na; ++aid2) {
      if (!(doneAtoms[aid2])) {
        std::vector<int> atoms(4, -1);
        atoms[1] = aid2;
        const Atom *atom2 = mol.getAtomWithIdx(atoms[1]);
        int at2AtomicNum = atom2->getAtomicNum();

        // if atom is a N,O or C and SP2-hybridized
        if (((at2AtomicNum == 6) || (at2AtomicNum == 7) ||
             (at2AtomicNum == 8)) &&
            (atom2->getHybridization() == Atom::SP2)) {
          // get neighbors
          boost::tie(nbrIdx, endNbrs) = mol.getAtomNeighbors(atom2);
          // check if enough neighbours
          if (mol.getAtomDegree(atom2) != 3) {
            continue;
          }
          unsigned int i = 0;
          unsigned int isBoundToSP2O = 0;  // false
          for (; nbrIdx != endNbrs; ++nbrIdx) {
            const Atom *atomX = mol[*nbrIdx].get();
            atoms[i] = atomX->getIdx();
            // if the central atom is sp2 carbon and is bound to sp2 oxygen, set
            // a flag
            if (!isBoundToSP2O) {
              isBoundToSP2O =
                  ((at2AtomicNum == 6) && (atomX->getAtomicNum() == 8) &&
                   (atomX->getHybridization() == Atom::SP2));
            }
            if (!i) {
              ++i;
            }
            ++i;
          }
          atoms.push_back(at2AtomicNum);
          atoms.push_back(isBoundToSP2O);
          improperAtoms.push_back(atoms);
          /*if (verbose) {
            std::cout << "out-of-plane bend: " << atoms[0] << " " << atoms[1] <<
          " "
                << atoms[2] << " " << atoms[3] << std::endl;
          }*/
        }
      }  // if atom is a N,O or C and SP2-hybridized
    }

    // torsions for flat rings
    const RingInfo *rinfo =
        mol.getRingInfo();  // FIX: make sure we have ring info
    CHECK_INVARIANT(rinfo, "");
    const VECT_INT_VECT &atomRings = rinfo->atomRings();
    for (VECT_INT_VECT_CI rii = atomRings.begin(); rii != atomRings.end();
         rii++) {
      unsigned int rSize = rii->size();
      // we don't need to deal with 3 membered rings
      // and we do not treat rings greater than 6
      if (rSize < 4 || rSize > 6) {
        continue;
      }
      // loop over ring atoms
      for (unsigned int i = 0; i < rSize; ++i) {
        // proper torsions
        aid1 = (*rii)[i];
        aid2 = (*rii)[(i + 1) % rSize];
        aid3 = (*rii)[(i + 2) % rSize];
        aid4 = (*rii)[(i + 3) % rSize];
        bid2 = mol.getBondBetweenAtoms(aid2, aid3)->getIdx();
        // if all 4 atoms are SP2, add torsion
        if (!(doneBonds[bid2]) &&
            (mol.getAtomWithIdx(aid1)->getHybridization() == Atom::SP2) &&
            (mol.getAtomWithIdx(aid2)->getHybridization() == Atom::SP2) &&
            (mol.getAtomWithIdx(aid3)->getHybridization() == Atom::SP2) &&
            (mol.getAtomWithIdx(aid4)->getHybridization() == Atom::SP2)) {
          doneBonds[bid2] = 1;
          std::vector<int> atoms(4);
          atoms[0] = aid1;
          atoms[1] = aid2;
          atoms[2] = aid3;
          atoms[3] = aid4;
          expTorsionAtoms.push_back(atoms);
          std::vector<int> signs(6, 1);
          signs[1] = -1;  // MMFF sign for m = 2
          std::vector<double> fconsts(6, 0.0);
          fconsts[1] = 100.0;  // 7.0 is MMFF force constants for aromatic rings
          expTorsionAngles.push_back(std::make_pair(signs, fconsts));
          /*if (verbose) {
            std::cout << "SP2 ring: " << aid1 << " " << aid2 << " " << aid3 << "
          " << aid4 << std::endl;
          }*/
        }

      }  // loop over atoms in ring
    }    // loop over rings
  }      // if useBasicKnowledge

}  // end function

}  // namespace CrystalFF
}
